package pl.edu.mimuw.irs.rcp.controller.editor.roles.handler;

import java.util.Set;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.handlers.HandlerUtil;

import pl.edu.mimuw.irs.core.model.design.net.IRSWorkflow;
import pl.edu.mimuw.irs.core.model.design.resource.Role;
import pl.edu.mimuw.irs.rcp.controller.editor.roles.command.RenameRoleCommand;
import pl.edu.mimuw.irs.rcp.controller.editor.roles.command.RenameWorkflowRoleCommand;
import pl.edu.mimuw.irs.rcp.controller.editor.workflow.handler.AbstractCommandStackSelectionHandler;
import pl.edu.mimuw.irs.rcp.persistence.PersistenceManager;
import pl.edu.mimuw.irs.rcp.util.Logger;
import pl.edu.mimuw.irs.rcp.util.MessageCode;
import pl.edu.mimuw.irs.rcp.util.UITexts;

public class RenameRoleHandler extends AbstractCommandStackSelectionHandler {

	// *** Attributes
	
	private CommandStack stack;
	private IRSWorkflow workflow;
	
	// *** Methods

	@Override
	protected Object execute(ExecutionEvent event, CommandStack stack,
			Object[] selection) throws ExecutionException {
		
		Shell shell = HandlerUtil.getActiveShell(event);
		/* We must check if workflow does not use this role */
		IEditorPart editor = HandlerUtil.getActiveEditor(event);
		if (editor == null) return null;
		IEditorInput input = editor.getEditorInput();
		if (input == null) return null;
		try {
			PersistenceManager manager = PersistenceManager.getInstance(input);
			if (manager == null) throw new Exception(input.toString());
			workflow = manager.getWorkflow();
			if (workflow == null) throw new Exception(input.toString());
		} catch (Exception e) {
			Logger.handle(MessageCode.PERSISTENCE_MANAGER_PROBLEM, e, input.getName());
			return false;
		}
		
		this.stack = stack;
		
		for (Object object : selection) {
			if (object instanceof Role) {
				Role role = (Role) object;

				rename(shell, role);
			}
		}
		
		return null;
	}

	protected void rename(Shell shell, Role role) {
		//MessageBox dialog = new MessageBox(shell, SWT.OK | SWT.CANCEL | SWT.ICON_QUESTION);
		new TextPrompt(shell, role);
	}
	
	public class TextPrompt {
		public TextPrompt(Shell shell, final Role role) {
			final Shell dialog = new Shell (shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
			FormLayout formLayout = new FormLayout();
			formLayout.marginWidth = 10;
			formLayout.marginHeight = 10;
			formLayout.spacing = 10;
			dialog.setLayout (formLayout);
			dialog.setText(UITexts.get(MessageCode.QUESTION_TITLE));
	
			final Label label = new Label (dialog, SWT.NONE);
			label.setText(UITexts.get(MessageCode.ROLE_RENAME_QUESTION));
			FormData data = new FormData();
			label.setLayoutData (data);
	
			Button cancel = new Button (dialog, SWT.PUSH);
			cancel.setText(UITexts.get(MessageCode.BUTTON_CANCEL));
			data = new FormData();
			data.width = 60;
			data.right = new FormAttachment (100, 0);
			data.bottom = new FormAttachment (100, 0);
			cancel.setLayoutData (data);
			cancel.addSelectionListener (new SelectionAdapter () {
				public void widgetSelected(SelectionEvent e) {
					dialog.close ();
				}
			});
	
			final Text text = new Text (dialog, SWT.BORDER);
			data = new FormData ();
			data.width = 200;
			data.left = new FormAttachment (label, 0, SWT.DEFAULT);
			data.right = new FormAttachment (100, 0);
			data.top = new FormAttachment (label, 0, SWT.CENTER);
			data.bottom = new FormAttachment (cancel, 0, SWT.DEFAULT);
			text.setLayoutData (data);
			text.setText(role.getName());
	
			Button ok = new Button (dialog, SWT.PUSH);
			ok.setText(UITexts.get(MessageCode.BUTTON_OK));
			data = new FormData ();
			data.width = 60;
			data.right = new FormAttachment (cancel, 0, SWT.DEFAULT);
			data.bottom = new FormAttachment (100, 0);
			ok.setLayoutData (data);
			ok.addSelectionListener (new SelectionAdapter () {
				public void widgetSelected (SelectionEvent e) {
					if (tryToChangeName(role, text.getText())) dialog.close();
					else label.setText(UITexts.get(MessageCode.ROLE_RENAME_EXISTS_QUESTION));
				}
			});
	
			dialog.setDefaultButton (ok);
			dialog.pack ();
			dialog.open ();
		}

	}

	protected boolean tryToChangeName(Role role, String newName) {
		/* Check if such name exists */
		if (role.getRoles().keySet().contains(newName)) return false;
		
		Command command;
		if (newName == null) return false;
		
		Set<Role> usedRoles = workflow.getUsedRoles();
		if (usedRoles.contains(role)) {
			CompoundCommand compound = new CompoundCommand();
			compound.add(new RenameWorkflowRoleCommand(workflow, role, newName));
			compound.add(new RenameRoleCommand(role, newName));
			command = compound;
		} else {
			command = new RenameRoleCommand(role, newName);
		}
		stack.execute(command);
		return true;
	}
}
